﻿// owner 蒋家伟

#include "TaskTransferWorker.h"

// jsdk
#include "TaskManager.h"
#include "TaskId.h"
#include "TaskGroup.h"
#include "Dbg_Warn_Define.h"
#include "IDeviceManager.h"
#include "IDevice.h"
#include "StringUtils.h"
#include "ITaskDescription.h"
#include "TaskEvent.h"
#include "TaskEventArgs.h"

using namespace jsdk;

OwnerPtr<jsdk::TaskTransferWorker> jsdk::TaskTransferWorker::create()
{
    return NEW_AS_OWNERPTR(TaskTransferWorker);
}

void jsdk::TaskTransferWorker::onTaskReadyRead(QVariant vTaskId) const
{
    // 来一个新任务，将任务分发出去
    const IDeviceManager* pDeviceManager = IDeviceManager::get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDeviceManager, L"设备管理器未初始化", L"蒋家伟", L"2023-07-31");
    TaskId taskId = vTaskId.value<TaskId>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(taskId.isValid(), L"传递了一个无效的任务ID", L"蒋家伟", L"2023-07-31");

    TaskManager& taskManager = TaskManager::get();
    ITask* pTask = taskManager.getTaskFWByTaskId(taskId);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTask, L"ID:" + StringUtils::toWString(pTask->getTaskId().toValue()) + L"有效但任务为空", L"蒋家伟", L"2023-07-31");
    if (!taskDistribution(*pDeviceManager, taskManager, *pTask))
    {
        if (const ITaskDescription* pTaskDescription = pTask->getTaskDescription())
        {
            DBG_WARN_UNLESS(false, L"ID:" + StringUtils::toWString(pTask->getTaskId().toValue()) + L", 任务描述: < " + pTaskDescription->getDescription() + L" >分发失败", L"蒋家伟", L"2023-07-31");
        }
        else
        {
            DBG_WARN_UNLESS(false, L"ID:" + StringUtils::toWString(pTask->getTaskId().toValue()) + L"任务分发失败", L"蒋家伟", L"2023-07-31");
        }

        // 任务通知失败则丢弃任务
        TaskEventArgs args(TaskEventType::TaskNotifiedFail, taskId);
        TaskEvent::get().sendEvent(&args);
    }
}

void jsdk::TaskTransferWorker::onTaskReadyRead() const
{
    const IDeviceManager* pDeviceManager = IDeviceManager::get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDeviceManager, L"设备管理器未初始化", L"蒋家伟", L"2023-07-31");
    TaskManager& taskManager = TaskManager::get();
    for (auto iter : taskManager.getAllTaskWithoutDelayTime())
    {
        DBG_WARN_AND_CONTINUE_UNLESS(iter, L"任务指针无效", L"蒋家伟", L"2023-08-17");
        if (!taskDistribution(*pDeviceManager, taskManager, *iter))
        {
            if (const ITaskDescription* pTaskDescription = iter->getTaskDescription())
            {
                DBG_WARN_UNLESS(false, L"ID:" + StringUtils::toWString(iter->getTaskId().toValue()) + L", 任务描述: < " + pTaskDescription->getDescription() + L" >分发失败", L"蒋家伟", L"2023-07-31");
            }
            else
            {
                DBG_WARN_UNLESS(false, L"ID:" + StringUtils::toWString(iter->getTaskId().toValue()) + L"任务分发失败", L"蒋家伟", L"2023-07-31");
            }

            TaskEventArgs args(TaskEventType::TaskNotifiedFail, iter->getTaskId());
            TaskEvent::get().sendEvent(&args);
        }
    }
}

bool jsdk::TaskTransferWorker::taskDistribution(const IDeviceManager & deviceManager, TaskManager & taskManager, ITask& task) const
{
    if (TaskGroup* pTaskGroup = dynamic_cast<TaskGroup*>(&task))
    {
        // 把任务组的任务拆分放入任务管理器，然后获取并传递
        for (const auto& taskId : taskManager.splitTaskGroup(pTaskGroup))
        {
            const ITask* pChildrenTask = taskManager.getTaskByTaskId(taskId);
            DBG_WARN_AND_CONTINUE_UNLESS(pChildrenTask, L"任务组中存在空的子任务", L"蒋家伟", L"2023-07-31");
            const ITaskDescription* pTaskDescription = pChildrenTask->getTaskDescription();
            DBG_WARN_AND_CONTINUE_UNLESS(pTaskDescription, L"ID:" + StringUtils::toWString(taskId.toValue()) + L"缺少任务描述", L"蒋家伟", L"2023-07-31");
            const IDevice* pDevice = deviceManager.getDeviceByName(pTaskDescription->getExecutorName());
            DBG_WARN_AND_CONTINUE_UNLESS(pDevice, pTaskDescription->getExecutorName() + L"没有注册设备", L"蒋家伟", L"2023-07-31");

            // 目标任务即将开始
            TaskEventArgs args(TaskEventType::TaskNotified, taskId);
            TaskEvent::get().sendEvent(&args);
            pDevice->addTask(taskId);
        }
    }
    else
    {
        // 将任务传递
        const TaskId& taskId = task.getTaskId();
        const ITaskDescription* pTaskDescription = task.getTaskDescription();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pTaskDescription, L"ID:" + StringUtils::toWString(taskId.toValue()) + L"缺少任务描述", L"蒋家伟", L"2023-07-31");
        const IDevice* pDevice = deviceManager.getDeviceByName(pTaskDescription->getExecutorName());
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pDevice, pTaskDescription->getExecutorName() + L"没有注册设备", L"蒋家伟", L"2023-07-31");

        // 目标任务即将开始
        TaskEventArgs args(TaskEventType::TaskNotified, taskId);
        TaskEvent::get().sendEvent(&args);
        pDevice->addTask(taskId);
    }

    return true;
}
